package com.dynamo.transport.network.practise.bootstrap;

import com.dynamo.transport.network.practise.channel.*;
import com.dynamo.transport.network.practise.channel.socket.nio.*;

import java.net.SocketAddress;
import java.util.concurrent.Executor;

/**
 * @author duanyimiao
 * @create 2018-12-18 5:32 PM
 * @description 将ChannelPipeline NioWorker NioBoss这些类关联起来
 **/
public class ServerBootstrap extends Bootstrap {

    private Executor boss;
    private Executor worker;
    private NioBossPool bossPool;
    private NioServerSocketChannel serverSocketChannel;

    //TODO 如何使用ChannelFactory来创建Channel
    public ServerBootstrap(Executor boss, Executor worker, Class<? extends Channel> channel, SocketAddress localSocketAddress) {

        this.boss = boss;
        this.worker = worker;
        this.bossPool = new NioBossPool(boss, 1);
        NioWorkerPool workerPool = new NioWorkerPool(worker, 6);
        ChannelPipeline pipeline = Channels.getPipeline();
        pipeline.addLast("binder", new Binder());
        pipeline.addLast("encoder",new EncoderHandler());
        pipeline.addLast("logic",new SimpleChannelUpstreamHandler());
        this.serverSocketChannel = new NioServerSocketChannel(localSocketAddress, pipeline, bossPool, workerPool);
        //当绑定成功了再去监听 监听客户端的连接
        System.out.println("register accept channel to selector");
        ((NioBoss) bossPool.nextBoss()).register(serverSocketChannel, null);



    }

    public void start(SocketAddress localSocketAddress) {


    }

    private class Binder extends SimpleChannelUpstreamHandler {

        @Override
        public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) {
            System.out.println("channel has been create");
            //TODO 通过ChannelConfig配置Channel

            //TODO 明显直接写死的NioChannelSink，这里如何满足开闭原则
            e.getPipelien().attach(e.getChannel(), new NioChannelSink());
            //向Downstream Handler发其bind事件
            //门面模式，当需要更换ChannelPipeline实现时只需要更改其门面类Channels即可
            Channels.bind(e.getPipelien(), e.getChannel());


        }

    }


}
